package com.cskaoyan.javase.oop3._2inner._4local._2usecase;

import com.sun.org.apache.regexp.internal.RE;
import sun.security.x509.AVA;

/**
 * 局部内部类经常使用在以下两个场景中：
 *      1.方法需要返回一个对象，返回值类型是引用数据类型时。
 *          方法的返回值类型是一个类,抽象类或者接口时.
 *
 *      法需要返回一个对象时，可以在方法的局部位置写一个 局部内部类 继承/实现外部的类/接口，创建对象后作为返回值。
 *      这是因为方法的返回值可以是返回值类型的对象，也可以是子类对象（当返回值类型是引用数据类型时）。
 *
 *      2.方法需要传入一个对象，形参数据类型是引用数据类型时。
 *      方法需要传入一个对象实参时，可以在调用方法的位置定义一个 局部内部类 来继承/实现外部的类/接口，创建对象后作为方法的实参传入。这是因为方法的实参可以是形参类型的对象，也可以子类对象（当返回值类型是引用数据类型时）。
 *
 * 使用局部内部类的优点：
 *      1.绝对对外界隐藏，封装。
 *      2.相比较于传统的定义类，然后创建对象，它相对更加简洁省事。(稍微简单一丢丢)
 *          当然这个优点会在随后匿名内部.Lambda表达式中得已发回
 *
 * 缺点：
 *      这个类是一次性的。
 *
 * 综上，假如在局部位置需要一次性的使用某个对象，可以使用局部内部类创建它，
 *      但是如果多次在不同的方法中使用，使用局部内部类就得不偿失了。
 *
 * @since 15:07
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        BaseA a = method();
        a.test();

        System.out.println("-------------");

        method(new IAImpl());

        // 定义局部内部类
        class IAImpl implements IA{
            @Override
            public int test() {
                return 777;
            }
        }
        method(new IAImpl());
    }

    public static BaseA method() {
        // 常规的做法
        // return new A();

        // 用局部内部类的做法
        class A extends BaseA {
            @Override
            public void test() {
                System.out.println("我是局部内部类的实现,我比你高级!");
            }
        }
        return new A();
    }

    public static B method2() {
        // return new B();
        class BSon extends B {
        }
        return new BSon();
    }

    public static void method(IA a){
        System.out.println(a.test());
    }


}
class IAImpl implements IA{
    @Override
    public int test() {
        return 666;
    }
}
interface IA {
    int test();
}

class B {
}

abstract class BaseA {
    public abstract void test();
}

class A extends BaseA {
    @Override
    public void test() {
        System.out.println("hello world!");
    }
}